/* $Id: JuggerTournament.java 39 2009-07-24 22:48:06Z h_m_r@gmx.de $ */
package org.jugger.tournament.gui;

import java.awt.Component;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.net.MalformedURLException;
import java.util.Locale;
import java.util.Properties;
import java.util.Vector;

import javax.swing.JDesktopPane;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;

import org.jugger.tournament.gui.view.EditTeamDialog;
import org.jugger.tournament.gui.view.NewTournamentDialog;
import org.jugger.tournament.gui.view.TournamentFrame;
import org.jugger.tournament.model.Team;
import org.jugger.tournament.model.Tournament;
import org.jugger.tournament.model.loader.TournamentLoader;
import org.jugger.tournament.model.writer.TournamentXmlWriter;

import util.I18N;
import util.Settings;

/**
 * @author Sven Hamer
 */
public class JuggerTournament extends JFrame {

	public static final String name = "Jugger Tournament";
	public static final String version = "0.1.0 dev/beta";
	public static final String author = "Sven Hamer aka Bunny/LMS";
	public static final String title = name + " <" + version + "> | " + author;

	public static final String homepageUrl = "http://code.google.com/p/juggertournament/";
	public static final String onlineHelpUrl = "http://code.google.com/p/juggertournament/wiki/Usage?wl=%LOCALE%";
	public static final String forumUrl = "http://forum.jugger.org/";

	private static final long serialVersionUID = -4493384338453173761L;
	private JDesktopPane desktop;

	private File currentFileChooserPath = new File("./");

	private JMenuItem menuTournamentNew;
	private JMenuItem menuTournamentOpen;
	private JMenuItem menuTournamentSave;
	private JMenuItem menuTournamentSaveAs;


	private final Vector<TournamentFrame> tournamentFrames = new Vector<TournamentFrame>();

	private JuggerTournament() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		I18N.setResourceBundle("Messages_jugger", Settings.getLocale());
		setTitle(title);

		desktop = new JDesktopPane();
		setContentPane(desktop);
		desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);

		// menu
		//Create the menu bar.
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);

		menuBar.add(createTournamentMenu());
		menuBar.add(createLocalesMenu());
		menuBar.add(createHelpMenu());

		updateMenuStates();

		// Display the window.
		pack();
		setSize(920, 710);
		setVisible(true);
	}

	private JMenu createTournamentMenu() {
		JMenu menuTournament = new JMenu(I18N.__("menuTournament"));
		menuTournament.setMnemonic(KeyEvent.VK_T);
		menuTournamentNew = new JMenuItem(I18N.__("menuTournamentNew"), KeyEvent.VK_N);
		menuTournamentNew.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
		menuTournament.add(menuTournamentNew);
		menuTournamentOpen = new JMenuItem(I18N.__("menuTournamentOpen"), KeyEvent.VK_O);
		menuTournamentOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK));
		menuTournament.add(menuTournamentOpen);
		menuTournamentSave = new JMenuItem(I18N.__("menuTournamentSave"), KeyEvent.VK_S);
		menuTournamentSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
		menuTournament.add(menuTournamentSave);
		menuTournamentSaveAs = new JMenuItem(I18N.__("menuTournamentSaveAs"), KeyEvent.VK_A);
		menuTournamentSaveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK+ActionEvent.SHIFT_MASK));
		menuTournament.add(menuTournamentSaveAs);

		menuTournamentNew.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Tournament tournament = NewTournamentDialog.showDialog(desktop, desktop);
				newTournamentFrame(tournament, null);
			}
		});
		menuTournamentOpen.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				JFileChooser chooser = new JFileChooser(I18N.__("menuTournamentOpen"));
				chooser.setDialogType(JFileChooser.OPEN_DIALOG);
				chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
				chooser.setCurrentDirectory(currentFileChooserPath);
				chooser.setVisible(true);
		        if (chooser.showOpenDialog(desktop) == JFileChooser.APPROVE_OPTION) {
		        	File inputFile = chooser.getSelectedFile();
		        	currentFileChooserPath = chooser.getCurrentDirectory();
					Tournament tournament;
					boolean success = true;
					try {
						tournament = TournamentLoader.loadFromXML(inputFile.toURI().toURL());
						success = tournament != null;
						newTournamentFrame(tournament, inputFile);
					} catch (MalformedURLException e) {
						// TODO: fehlermeldung
					}

					if(!success) {
						JOptionPane.showMessageDialog(desktop, I18N.__("invalidTournamentFile"));
					}
		        }
			}
		});
		menuTournamentSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				saveCurrentTournament();
			}
		});
		menuTournamentSaveAs.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				saveAsCurrentTournament();
			}
		});

		return menuTournament;
	}

	private JMenu createLocalesMenu() {
		JMenu menu = new JMenu(I18N.__("menuLocale"));
		JMenuItem item;
		item = new JMenuItem(I18N.__("menuLocale_en"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Settings.setLocale(Locale.ENGLISH);
				I18N.setLocale(Locale.ENGLISH);
				showRestartNeededDialog();
			}
		});
		menu.add(item);
		item = new JMenuItem(I18N.__("menuLocale_de"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Settings.setLocale(Locale.GERMAN);
				I18N.setLocale(Locale.GERMAN);
				showRestartNeededDialog();
			}
		});
		menu.add(item);
		return menu;
	}

	private void openUrl(String url) {
		if (!java.awt.Desktop.isDesktopSupported()) {
			System.err.println("Desktop is not supported");
			return;
		}
		java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
		if (!desktop.isSupported(java.awt.Desktop.Action.BROWSE)) {
			System.err.println("Desktop doesn't support the browse action (fatal)");
			return;
		}
		try {
			java.net.URI uri = new java.net.URI(url);
			desktop.browse(uri);
		} catch (Exception e) {
		}
	}

	private JMenu createHelpMenu() {
		JMenu menu = new JMenu(I18N.__("menuHelp"));
		JMenuItem item;
		item = new JMenuItem(I18N.__("menuHelpOnlineHelp"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				// TODO: url öffnen
				openUrl(onlineHelpUrl.replaceAll("%LOCALE%", Settings.getLocale().getLanguage()));
			}
		});
		menu.add(item);
		item = new JMenuItem(I18N.__("menuHelpHomepage"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				openUrl(homepageUrl.replaceAll("%LOCALE%", Settings.getLocale().getLanguage()));
			}
		});
		menu.add(item);
		item = new JMenuItem(I18N.__("menuHelpForum"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				openUrl(forumUrl.replaceAll("%LOCALE%", Settings.getLocale().getLanguage()));
			}
		});
		menu.add(item);
		menu.addSeparator();
		item = new JMenuItem(I18N.__("menuHelpInfo"));
		item.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				showInfoDialog();
			}
		});
		menu.add(item);
		return menu;
	}

	private void showRestartNeededDialog() {
		JOptionPane.showMessageDialog(
			this,
			I18N.__("dialogTextRestartNeeded"),
		    I18N.__("dialogTitleRestartNeeded"),
		    JOptionPane.INFORMATION_MESSAGE,
		    null
		);
	}

	private void showInfoDialog() {
		InfoDialog.showDialog(this, this);
	}

	private void newTournamentFrame(Tournament tournament, File file) {
		if(tournament == null)
			return;

		TournamentFrame frame = new TournamentFrame(tournament, file);
		tournamentFrames.add(frame);
		getContentPane().add(frame);

		frame.addInternalFrameListener(new InternalFrameListener() {
			public void internalFrameActivated(InternalFrameEvent arg0) {
				// TODO Auto-generated method stub

			}
			public void internalFrameClosed(InternalFrameEvent e) {
				tournamentFrames.remove(e.getInternalFrame());
				updateMenuStates();
			}
			public void internalFrameClosing(InternalFrameEvent e) {
				// TODO Auto-generated method stub

			}
			public void internalFrameDeactivated(InternalFrameEvent arg0) {
				// TODO Auto-generated method stub

			}
			public void internalFrameDeiconified(InternalFrameEvent arg0) {
				// TODO Auto-generated method stub

			}
			public void internalFrameIconified(InternalFrameEvent arg0) {
				// TODO Auto-generated method stub

			}
			public void internalFrameOpened(InternalFrameEvent arg0) {
				// TODO Auto-generated method stub

			}

		});

		frame.setVisible(true);
		updateMenuStates();
	}

	private void saveAsCurrentTournament() {
		JInternalFrame selectedFrame = desktop.getSelectedFrame();
		if(selectedFrame != null && selectedFrame instanceof TournamentFrame) {
        	TournamentFrame tournamentFrame = (TournamentFrame)selectedFrame;
			JFileChooser chooser = new JFileChooser(I18N.__("menuTournamentSave")) {
				private static final long serialVersionUID = 0L;
				@Override
	            public void approveSelection() {
	                File f = getSelectedFile();
	                if(f.exists() && getDialogType() == SAVE_DIALOG) {
	                    int result = JOptionPane.showConfirmDialog(getTopLevelAncestor(),
	                            "The selected file already exists. " +
	                            "Do you want to overwrite it?",
	                            "The file already exists",
	                            JOptionPane.YES_NO_OPTION,
	                            JOptionPane.QUESTION_MESSAGE);
	                    switch(result)  {
	                    case JOptionPane.YES_OPTION:
	                        super.approveSelection();
	                        return;
	                    case JOptionPane.NO_OPTION:
	                        return;
	                    }
	                }
	                super.approveSelection();
	            }
			};
			chooser.setDialogType(JFileChooser.SAVE_DIALOG);
			chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
			chooser.setCurrentDirectory(currentFileChooserPath);
			chooser.setVisible(true);
	        if (chooser.showSaveDialog(desktop) == JFileChooser.APPROVE_OPTION) {
	        	File saveFile = chooser.getSelectedFile();
	        	currentFileChooserPath = chooser.getCurrentDirectory();

	        	// set file and invoke save-action
	        	if(saveFile != null) {
	        		tournamentFrame.setFile(saveFile);
	        		saveCurrentTournament();
	        	}
	        }
		}
	}
	private void saveCurrentTournament() {
		JInternalFrame selectedFrame = desktop.getSelectedFrame();
		if(selectedFrame != null && selectedFrame instanceof TournamentFrame) {
        	TournamentFrame tournamentFrame = (TournamentFrame)selectedFrame;
			if(tournamentFrame.getFile() == null) {
				// call save as first! (that will invoke this action again if successful)
				saveAsCurrentTournament();
			}
			else {
				TournamentXmlWriter.writeToXML(tournamentFrame.getFile().toURI(), tournamentFrame.getTournament());
			}
		}
	}

	public void updateMenuStates() {
		menuTournamentNew.setEnabled(true);
		menuTournamentOpen.setEnabled(true);
		menuTournamentSave.setEnabled(desktop.getSelectedFrame() != null);
		menuTournamentSaveAs.setEnabled(desktop.getSelectedFrame() != null);
	}

	public static void main(String[] args) {
		try {
			UIManager.setLookAndFeel(
			// UIManager.getSystemLookAndFeelClassName()
					// UIManager.getCrossPlatformLookAndFeelClassName()
					// "com.sun.java.swing.plaf.motif.MotifLookAndFeel"
					"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"

					);
		} catch (Exception e) {
			try {
				UIManager.setLookAndFeel(UIManager
						.getSystemLookAndFeelClassName());
			} catch (Exception e2) {
			}
		}

		// Schedule a job for the event dispatch thread:
		// creating and showing this application's GUI.
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				new JuggerTournament();
			}
		});
	}

}
